<template>
  <ControlWrap :full-height="false">
      <!-- 左右卡片布局 -->
      <div
        class="h-full grid gap-4 grid-cols-[repeat(auto-fill,minmax(440px,1fr))]"
      >
        <!-- 字典分类卡片 -->
        <el-card class="w-full">
          <template #header>
            <div class="card-header">
              <span>字典分类</span>
            </div>
          </template>
          <!-- 搜索表单 -->
          <div class="mb-4 flex items-center gap-4">
            <el-form :inline="true" class="flex-1">
              <el-form-item label="创建时间">
                <el-date-picker
                  v-model="searchForm.dateRange"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  class="!w-[360px]"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  :default-time="[
                    new Date(2000, 1, 1, 0, 0, 0, 0),
                    new Date(2000, 1, 1, 23, 59, 59),
                  ]"
                />
              </el-form-item>
              <el-form-item>
                <el-input
                  v-model.trim="searchForm.keyword"
                  value-format="YYYY-MM-DD"
                  clearable
                  placeholder="搜索字典名/字典类型"
                  class="!w-[200px]"
                >
                  <template #prefix>
                    <el-icon class="text-gray-400">
                      <Search />
                    </el-icon>
                  </template>
                </el-input>
              </el-form-item>
              <el-form-item>
                <el-button
                  type="primary"
                  @click="handleAddDict"
                  class="!rounded-button whitespace-nowrap"
                >
                  新增字典
                </el-button>
                <el-button
                  type="primary"
                  @click="handleSearch"
                  class="!rounded-button whitespace-nowrap"
                >
                  查询
                </el-button>
                <el-button
                  @click="handleReset"
                  class="!rounded-button whitespace-nowrap"
                >
                  重置
                </el-button>
              </el-form-item>
            </el-form>
          </div>
          <!-- 字典列表表格 -->
          <div class="rounded-lg bg-white shadow">
            <el-table
              :data="dictData"
              @row-click="handleRowClick"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="55" />
              <el-table-column prop="dict_name" label="字典名称" width="180" />
              <el-table-column prop="code" label="字典编码" width="180" />
              <el-table-column prop="status" label="状态" width="100">
                <template #default="{ row }">
                  <el-tag :type="row.status ? 'danger' : 'success'">
                    {{ row.status ? "禁用" : "启用" }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column prop="description" label="描述" />
              <el-table-column label="创建时间" width="200">
                <template #default="{ row }">
                  {{ dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss") }}
                </template>
              </el-table-column>
              <el-table-column label="更新时间" width="200">
                <template #default="{ row }">
                  {{ dayjs(row.updateTime).format("YYYY-MM-DD HH:mm:ss") }}
                </template>
              </el-table-column>
              <el-table-column label="操作" fixed="right" width="200">
                <template #default="{ row }">
                  <el-button
                    @click.stop="handleEditDict(row)"
                    type="primary"
                    class="!rounded-button whitespace-nowrap"
                    plain
                  >
                    编辑
                  </el-button>
                  <el-button
                    @click.stop="handleDeleteDict(row)"
                    type="danger"
                    class="!rounded-button whitespace-nowrap"
                    plain
                  >
                    删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
          <!-- 分页组件 -->
          <template #footer>
            <el-pagination
              @change="handlePageChange"
              size="small"
              class="w-full flex flex-wrap"
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :total="total"
              :page-sizes="[10, 20, 30, 50]"
              layout="total, sizes, prev, pager, next, jumper"
            />
          </template>
        </el-card>
        <el-card v-if="!currentDict" class="w-full">
          <el-empty
            description="请点击一行字典进行编辑"
            image="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png"
          />
        </el-card>
        <!-- 字典数据卡片 -->
        <el-card v-show="currentDict" class="w-full">
          <template #header>
            <div class="card-header">
              <span class="font-bold mr-1">[{{ currentDict?.dict_name }}]</span>
              <span>字典数据</span>
            </div>
          </template>
          <!-- 字典数据搜索和新增按钮 -->
          <div class="mb-4 flex">
            <div class="flex items-center gap-4">
              <el-input
                v-model="valueSearchQuery"
                placeholder="搜索标签名"
                clearable
                class="!w-[200px]"
              >
                <template #prefix>
                  <el-icon class="text-gray-400">
                    <Search />
                  </el-icon>
                </template>
              </el-input>
            </div>
            <el-button
              type="primary"
              @click="handleAddDictValue(currentDict)"
              class="!rounded-button whitespace-nowrap ml-4"
            >
              新增标签
            </el-button>
          </div>
          <!-- 字典数据列表表格 -->
          <el-table height="300px" :data="filteredDictList" style="width: 100%">
            <el-table-column prop="label" label="标签名" width="180" />
            <el-table-column prop="value" label="字典值" width="180" />
            <el-table-column prop="sort" label="排序号" width="100" />
            <el-table-column prop="status" label="状态" width="100">
              <template #default="{ row }">
                <el-tag :type="row.status ? 'danger' : 'success'">
                  {{ row.status ? "禁用" : "启用" }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column fixed="right" label="操作" width="200">
              <template #default="{ row }">
                <el-button
                  @click="handleEditDictValue(currentDict!, row)"
                  type="primary"
                  class="!rounded-button whitespace-nowrap"
                  plain
                >
                  编辑
                </el-button>
                <el-button
                  @click="handleDeleteDictValue(currentDict!, row)"
                  type="danger"
                  class="!rounded-button whitespace-nowrap"
                  plain
                >
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <!-- 保存更新字典按钮 -->
          <template #footer>
            <el-button
              type="primary"
              @click="handleSubmitDictValues"
              class="!rounded-button whitespace-nowrap"
            >
              保存更新字典
            </el-button>
          </template>
        </el-card>
      </div>
      <!-- 字典编辑弹窗 -->
      <el-dialog
        v-model="dictDialogVisible"
        :title="editingDict.dict_id ? '编辑字典' : '新增字典'"
        width="500px"
      >
        <el-form :model="editingDict" label-width="100px">
          <el-form-item label="字典名称">
            <el-input v-model="editingDict.name" />
          </el-form-item>
          <el-form-item label="字典编码">
            <el-input v-model="editingDict.code" />
          </el-form-item>
          <el-form-item label="描述">
            <el-input v-model="editingDict.description" type="textarea" />
          </el-form-item>
          <el-form-item label="描述">
            <el-select
              v-model="editingDict.status"
              placeholder="状态"
              class="!w-[120px]"
            >
              <el-option label="启用" :value="0" />
              <el-option label="禁用" :value="1" />
            </el-select>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button
              @click="dictDialogVisible = false"
              class="!rounded-button whitespace-nowrap"
            >
              取消
            </el-button>
            <el-button
              type="primary"
              @click="handleSaveDict"
              class="!rounded-button whitespace-nowrap"
            >
              确定
            </el-button>
          </span>
        </template>
      </el-dialog>
      <!-- 字典值编辑弹窗 -->
      <el-dialog
        v-model="dictValueDialogVisible"
        :title="editingDictValue.id ? '编辑字典值' : '新增字典值'"
        width="500px"
      >
        <el-form :model="editingDictValue" label-width="100px">
          <el-form-item label="标签名">
            <el-input v-model="editingDictValue.label" />
          </el-form-item>
          <el-form-item label="字典值">
            <el-input v-model="editingDictValue.value" />
          </el-form-item>
          <el-form-item label="排序号">
            <el-input-number
              v-model="editingDictValue.sort"
              :min="0"
              :max="100"
              :precision="0"
            />
          </el-form-item>
          <el-form-item label="状态">
            <el-select
              v-model="editingDictValue.status"
              placeholder="状态"
              class="!w-[120px]"
            >
              <el-option label="启用" :value="0" />
              <el-option label="禁用" :value="1" />
            </el-select>
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button
              @click="dictValueDialogVisible = false"
              class="!rounded-button whitespace-nowrap"
            >
              取消
            </el-button>
            <el-button
              type="primary"
              @click="handleSaveDictValue"
              class="!rounded-button whitespace-nowrap"
            >
              确定
            </el-button>
          </span>
        </template>
      </el-dialog>
  </ControlWrap>
</template>

<script lang="ts" setup>
import { ref, onMounted, getCurrentInstance, computed } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Search } from "@element-plus/icons-vue";
import { addDict, getDictList, deleteDict, editDict } from "@/api/dict";
import dayjs from "dayjs";
// 数据类型定义
/**
 * 字典值数据类型
 */
interface DictValue {
  id: number;
  label: string;
  value: string;
  sort: number;
  status: boolean;
}

/**
 * 字典数据类型
 */
interface Dict {
  dict_id: number;
  name: string;
  code: string;
  description: string;
  dict_list: DictValue[];
  expanded: boolean;
  status: number;
}

// 状态变量
const { proxy }: any = getCurrentInstance();
/**
 * 字典编辑弹窗显示状态
 */
const dictDialogVisible = ref(false);
/**
 * 字典值编辑弹窗显示状态
 */
const dictValueDialogVisible = ref(false);
/**
 * 选中的字典列表
 */
const selectedDicts = ref<Dict[]>([]);
/**
 * 搜索表单数据
 */
const searchForm = ref({
  dateRange: [],
  keyword: "",
});
/**
 * 当前页码
 */
const currentPage = ref(1);
/**
 * 每页显示数量
 */
const pageSize = ref(10);
/**
 * 数据总数量
 */
const total = ref(100);
/**
 * 字典值搜索关键词
 */
const valueSearchQuery = ref("");
/**
 * 当前编辑的字典数据
 */
const editingDict = ref<any>({});
/**
 * 当前编辑的字典值数据
 */
const editingDictValue = ref<any>({});
/**
 * 当前选中的字典数据
 */
const currentDict = ref<any>(null);
/**
 * 字典列表数据
 */
const dictData = ref([]);
// 定义一个计算属性，用于过滤字典值列表
const filteredDictList = computed(() => {
  if (!currentDict.value || !valueSearchQuery.value) {
    return currentDict.value
      ? currentDict.value.dict_list.sort(
          (a: { sort: number }, b: { sort: number }) => a.sort - b.sort
        )
      : [];
  }
  const query = valueSearchQuery.value.toLowerCase();
  return currentDict.value.dict_list
    .sort((a: { sort: number }, b: { sort: number }) => a.sort - b.sort)
    .filter((item: any) => {
      return item.label.toLowerCase().includes(query);
    });
});
// 搜索相关方法
/**
 * 处理搜索操作
 */
const handleSearch = async () => {
  currentPage.value = 1;
  await getDictPageList();
};

/**
 * 处理重置搜索表单操作
 */
const handleReset = () => {
  searchForm.value.dateRange = [];
  searchForm.value.keyword = "";
  handleSearch();
};

// 字典操作相关方法
/**
 * 处理新增字典操作
 */
const handleAddDict = () => {
  editingDict.value = {
    name: "",
    code: "",
    description: "",
    status: 0,
  };
  dictDialogVisible.value = true;
};

/**
 * 处理编辑字典操作
 * @param row 当前选中的字典行数据
 */
const handleEditDict = (row: any) => {
  editingDict.value.name = row.dict_name;
  editingDict.value = Object.assign(editingDict.value, row);
  dictDialogVisible.value = true;
};

/**
 * 处理删除字典操作
 * @param row 当前选中的字典行数据
 */
const handleDeleteDict = (row: any) => {
  ElMessageBox.confirm("确认删除该字典吗？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    await deleteDict({
      dictId: row.dict_id,
      successMsg: true,
      errorMsg: true,
    });
    await getDictPageList();
  });
};

/**
 * 处理保存字典操作
 */
const handleSaveDict = () => {
  if (!editingDict.value.name || !editingDict.value.code) {
    ElMessage.warning("请填写必要信息");
    return;
  }
  if (editingDict.value.dict_id) {
    // 编辑字典
    const editOptions = {
      dictId: editingDict.value.dict_id,
      dictName: editingDict.value.name,
      code: editingDict.value.code,
      dictList: editingDict.value.dict_list,
      description: editingDict.value.description || "",
      status: editingDict.value.status || 0,
      successMsg: true,
      errorMsg: true,
    };
    editDict(editOptions)
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log(err);
      })
      .finally(async () => {
        dictDialogVisible.value = false;
        await getDictPageList();
      });
  } else {
    // 新增字典
    const newDict = {
      dictName: editingDict.value.name,
      code: editingDict.value.code,
      description: editingDict.value.description || "",
      dictList: JSON.stringify([]),
      status: editingDict.value.status || 0,
      successMsg: true,
      errorMsg: true,
    };
    addDict(newDict)
      .then((res) => {
        console.log(res);
      })
      .catch((err) => {
        console.log(err);
      })
      .finally(async () => {
        dictDialogVisible.value = false;
        await getDictPageList();
      });
  }
};

// 字典值操作相关方法
/**
 * 处理新增字典值操作
 * @param dict 当前选中的字典数据
 */
const handleAddDictValue = (dict: Dict | null) => {
  valueSearchQuery.value = "";
  if (!dict) return;
  editingDictValue.value = {
    label: "",
    value: "",
    sort: 0,
    status: 0,
  };
  dictValueDialogVisible.value = true;
};

/**
 * 处理编辑字典值操作
 * @param dict 当前选中的字典数据
 * @param row 当前选中的字典值行数据
 */
const handleEditDictValue = (dict: Dict, row: DictValue) => {
  editingDictValue.value = { ...row };
  currentDict.value = dict;
  dictValueDialogVisible.value = true;
};

/**
 * 处理删除字典值操作
 * @param dict 当前选中的字典数据
 * @param row 当前选中的字典值行数据
 */
const handleDeleteDictValue = (dict: any, row: DictValue) => {
  ElMessageBox.confirm("确认删除该字典值吗？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    const index = dict.dict_list.findIndex((item: any) => item.id === row.id);
    if (index !== -1) {
      dict.dict_list.splice(index, 1);
      ElMessage.success("删除成功");
    }
  });
};

/**
 * 处理保存字典值操作
 */
const handleSaveDictValue = () => {
  if (!editingDictValue.value.label || !editingDictValue.value.value) {
    ElMessage.warning("请填写必要信息");
    return;
  }
  if (!currentDict.value) return;
  if (editingDictValue.value.id) {
    const index = currentDict.value.dict_list.findIndex(
      (item: { id: number | undefined }) =>
        item.id === editingDictValue.value.id
    );
    if (index !== -1) {
      currentDict.value.dict_list[index] = {
        ...currentDict.value.dict_list[index],
        ...editingDictValue.value,
      } as DictValue;
    }
  } else {
    const newValue: DictValue = {
      id: Date.now(),
      label: editingDictValue.value.label,
      value: editingDictValue.value.value,
      sort: editingDictValue.value.sort || 0,
      status: editingDictValue.value.status || 0,
    };
    currentDict.value.dict_list.push(newValue);
  }
  dictValueDialogVisible.value = false;
};

// 表格相关方法
/**
 * 处理表格行选中变化操作
 * @param selection 当前选中的行数据列表
 */
const handleSelectionChange = (selection: Dict[]) => {
  selectedDicts.value = selection;
};

/**
 * 处理表格行点击操作
 * @param row 当前点击的行数据
 */
const handleRowClick = (row: any) => {
  const tempData = { ...row };
  tempData.dict_list = JSON.parse(tempData.dict_list);
  currentDict.value = tempData;
};

// 分页相关方法
/**
 * 处理分页变化操作
 */
const handlePageChange = async () => {
  await getDictPageList();
};

// 数据获取方法
/**
 * 获取字典分页列表数据
 */
const getDictPageList = async () => {
  try {
    const list = await getDictList({
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      keyword: searchForm.value.keyword ? searchForm.value.keyword : undefined,
      startTime:
        searchForm.value.dateRange && searchForm.value.dateRange.length > 0
          ? searchForm.value.dateRange[0]
          : undefined,
      endTime:
        searchForm.value.dateRange && searchForm.value.dateRange.length > 0
          ? searchForm.value.dateRange[1]
          : undefined,
      successMsg: true,
      errorMsg: true,
    });
    dictData.value = list.list;
    total.value = list.total;
  } catch (error) {
    console.log(error);
  } finally {
    currentDict.value = null;
  }
};

// 保存字典值列表方法
/**
 * 处理保存更新字典值列表操作
 */
const handleSubmitDictValues = () => {
  // 确保currentDict.value数组成员的字段都不能是空值
  if (
    currentDict.value.dict_list.some((item: any) =>
      Object.values(item).some(
        (value: any) => value === null || value === undefined || value === ""
      )
    )
  ) {
    ElMessage.warning("字典数据值各项不能为空");
    return;
  }
  ElMessageBox.confirm("确认保存该字典数据值吗？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    // 实现保存逻辑
    try {
      await editDict({
        dictId: currentDict.value.dict_id,
        dictName: currentDict.value.name,
        code: currentDict.value.code,
        dictList: JSON.stringify(currentDict.value.dict_list),
        description: currentDict.value.description,
        status: currentDict.value.status,
        successMsg: true,
        errorMsg: true,
      });
    } catch (error) {
    } finally {
      dictValueDialogVisible.value = false;
      await getDictPageList();
    }
  });
};

// 生命周期钩子
onMounted(async () => {
  await getDictPageList();
});
</script>

<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
:deep(.el-input-number .el-input__wrapper) {
  padding-left: 11px;
  padding-right: 11px;
}
:deep(.el-dialog__body) {
  padding-top: 20px;
}
</style>
